package com.atguigu.exam.service.impl;

import com.atguigu.exam.entity.*;
import com.atguigu.exam.mapper.AnswerRecordMapper;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.service.AnswerRecordService;
import com.atguigu.exam.service.ExamService;
import com.atguigu.exam.service.KimiAiService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.StartExamVo;
import com.atguigu.exam.vo.SubmitAnswerVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 考试服务实现类
 */
@Service
@Slf4j
public class ExamServiceImpl extends ServiceImpl<ExamRecordMapper, ExamRecord> implements ExamService {
    /**
     * 开始考试
     *
     * @param startExamVo
     * @return
     */
    @Autowired
    private PaperService paperService;
    @Autowired
    private AnswerRecordMapper answerRecordMapper;
    @Autowired
    private AnswerRecordService answerRecordService;
    @Autowired
    private KimiAiService kimiAiService;


    @Override
    public ExamRecord startExam(StartExamVo startExamVo) {
        //判断是否存在进行中的考试
        LambdaQueryWrapper<ExamRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ExamRecord::getExamId, startExamVo.getPaperId());
        lambdaQueryWrapper.eq(ExamRecord::getStudentName, startExamVo.getStudentName());
        lambdaQueryWrapper.eq(ExamRecord::getStatus, "进行中");
        if (getBaseMapper().exists(lambdaQueryWrapper)) {
            return getOne(lambdaQueryWrapper);
        }


        //为examRecord设置参数
        ExamRecord examRecord = new ExamRecord();
        examRecord.setStudentName(startExamVo.getStudentName());
        examRecord.setExamId(startExamVo.getPaperId());
        examRecord.setWindowSwitches(0);
        examRecord.setScore(0);
        //设置开始时间
        examRecord.setStartTime(LocalDateTime.now());
        examRecord.setStatus("进行中");
        //保存记录
        save(examRecord);

        //返回考试记录
        return examRecord;
    }


    /**
     * 根据ID获取考试记录详情
     *
     * @param id
     * @return
     */
    @Override
    public ExamRecord getExamRecordById(Integer id) {
        ExamRecord examRecord = getById(id);

        //1.获取试卷内容
        Paper paper = paperService.getPaperById(examRecord.getExamId());
        examRecord.setPaper(paper);

        //2.获取答题记录详情
        LambdaQueryWrapper<AnswerRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AnswerRecord::getExamRecordId, id);
        List<AnswerRecord> answerRecords = answerRecordMapper.selectList(lambdaQueryWrapper);
        //答题记录为空则直接返回该答题记录对象
        if (answerRecords == null) {
            examRecord.setAnswerRecords(new ArrayList<>());
            return examRecord;
        }

        //3.进行答题记录排序
        //获取题目集合
        List<Question> questions = paper.getQuestions();
        //获取题目id集合
        List<Long> ids = questions.stream().map(Question::getId).collect(Collectors.toList());
        //方案一：
//        Map<Integer, AnswerRecord> answerRecordMap = answerRecords.stream().collect(Collectors.toMap(
//                AnswerRecord::getQuestionId, answerRecord -> answerRecord));
//        //创建一个新的集合接受排序后的答题记录
//        List<AnswerRecord> orderAnswerRecords = new ArrayList<>();
//        //答题记录按照试卷的题目id进行排序
//        ids.forEach(asId -> orderAnswerRecords.add(answerRecordMap.get(asId.intValue())));

        //方案二：
        answerRecords.sort((o1, o2) -> Integer.compare(ids.indexOf(Long.valueOf(o1.getQuestionId())), ids.indexOf(Long.valueOf(o2.getIsCorrect()))));

        //设置答题记录
        examRecord.setAnswerRecords(answerRecords);
        //返回考试记录
        return examRecord;

    }

    /**
     * 提交答案
     *
     * @param examRecordId
     * @param answers
     */
    @Override
    public void submitAnswers(Integer examRecordId, List<SubmitAnswerVo> answers) throws InterruptedException {
        //获取考试记录对象
        ExamRecord examRecord = getById(examRecordId);
        if (examRecord == null || !"进行中".equals(examRecord.getStatus())) {
            throw new RuntimeException("考试记录不存在");
        }

        List<AnswerRecord> answerRecordList = new ArrayList<>();
        //转换SubmitAnswerVo为AnswerRecord
        answers.forEach(a -> answerRecordList.add(new AnswerRecord(examRecordId, a.getQuestionId(), a.getUserAnswer())));

        //添加答案记录
        answerRecordService.saveBatch(answerRecordList);

        //更新考试记录表
        examRecord.setStatus("已完成");
        examRecord.setEndTime(LocalDateTime.now());
        updateById(examRecord);

        //调用ai判卷
        gradeExam(examRecordId);
    }

    /**
     * AI判卷
     *
     * @param examRecordId
     * @return
     */
    @Override
    public ExamRecord gradeExam(Integer examRecordId) throws InterruptedException {
        //宏观：  获取考试记录相关的信息（考试记录对象 考试记录答题记录 考试对应试卷）
        //  进行循环判断（1.答题记录进行修改 2.总体提到总分数 总正确数量）  修改考试记录（状态 -》 已批阅  修改 -》 总分数）   进行ai评语生成（总正确的题目数量）
        //  修改考试记录表  返回考试记录对象


        //1.获取考试记录以及试卷、答题记录
        ExamRecord examRecord = getExamRecordById(examRecordId);
        if (examRecord == null) {
            throw new RuntimeException("考试记录不存在");
        }
        //获取所有答题记录
        List<AnswerRecord> answerRecords = examRecord.getAnswerRecords();
        //判断答题记录是否为空
        if (answerRecords.isEmpty()) {
            examRecord.setScore(0);
            examRecord.setStatus("已批阅");
            examRecord.setAnswers("答题记录为空,无法进行判卷");
            updateById(examRecord);
            return examRecord;
        }

        //获取试卷中所有的题目
        List<Question> questions = examRecord.getPaper().getQuestions();
        Map<Long, Question> questionMap = questions.stream().collect(Collectors.toMap(Question::getId, q -> q));

        //总分数
        int totalScore = 0;
        //总正确题数
        int totalRightCount = 0;

        //2.进行循环判卷
        for (AnswerRecord answerRecord : answerRecords) {
            try {
                Question question = questionMap.get(Long.valueOf(answerRecord.getQuestionId()));
                String userAnswer = answerRecord.getUserAnswer();
                String rightAnswer = question.getAnswer().getAnswer();
                //判断是否不为简答题
                if (!"TEXT".equals(question.getType())) {
                    if ("JUDGE".equals(question.getType())) {
                        userAnswer = normalizeJudgeAnswer(userAnswer);
                    }
                    if (rightAnswer.equals(userAnswer)) {
                        answerRecord.setScore(question.getPaperScore().intValue());
                        answerRecord.setIsCorrect(1);
                    }
                } else {
                    //简答题使用ai判卷
                    GradingResult result =
                            kimiAiService.gradeQuestion(question, userAnswer, question.getPaperScore().intValue());
                    answerRecord.setScore(result.getScore());

                    //判断答案是否正确
                    if (result.getScore() == 0) {
                        answerRecord.setIsCorrect(0);
                        answerRecord.setAiCorrection(result.getReason());
                    } else if (result.getScore() == question.getPaperScore().intValue()) {
                        answerRecord.setIsCorrect(1);
                        answerRecord.setAiCorrection(result.getFeedback());
                    } else {
                        answerRecord.setIsCorrect(2);
                        answerRecord.setAiCorrection(result.getReason());
                    }


                }

            } catch (Exception e) {
                answerRecord.setScore(0);
                answerRecord.setIsCorrect(0);
                answerRecord.setAiCorrection("判卷出错了");
            }
            //总分数
            totalScore += answerRecord.getScore();
            //题目总正确数
            if (answerRecord.getIsCorrect() == 1) {
                totalRightCount++;
            }
            //更新答题记录
            answerRecordService.updateById(answerRecord);

        }

        //调用ai生成考试评价

        String summary = kimiAiService.buildSummary(
                totalScore, examRecord.getPaper().getTotalScore().intValue(), questions.size(), totalRightCount);
        examRecord.setAnswers(summary);
        examRecord.setScore(totalScore);
        examRecord.setStatus("已批阅");
        updateById(examRecord);
        return examRecord;
    }

    /**
     * 标准化判断题答案，将T/F转换为TRUE/FALSE
     *
     * @param answer 原始答案
     * @return 标准化后的答案
     */
    private String normalizeJudgeAnswer(String answer) {
        if (answer == null || answer.trim().isEmpty()) {
            return "";
        }

        String normalized = answer.trim().toUpperCase();
        switch (normalized) {
            case "T":
            case "TRUE":
            case "正确":
                return "TRUE";
            case "F":
            case "FALSE":
            case "错":
                return "FALSE";
            default:
                return normalized;
        }
    }
}